package com.zw.a.basic.a13.demo11_lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//自定义的线程类MyThread, 用来实现模拟卖票
public class MyThread extends Thread {
    //1. 定义变量, 记录票数.
    private static int tickets = 100;      //细节1: 这里要加static, 以为4个窗口(线程)共享100张票.

    //定义Lock锁, 通过多态的形式实现,
    private static final Lock lock = new ReentrantLock();   //Lock锁是JDK5的特性, 叫: 互斥锁(拔高,扩展: 感兴趣的话, 自己了解下 多线程的等待唤醒机制, 看3个线程之间入门协调锁资源).

    //定义构造方法, 用来给线程设置名字.
    public MyThread() {
    }

    public MyThread(String name) {
        super(name);
    }

    //2. 在run()方法中实现模拟卖票
    @Override
    public void run() {
        //3.一直卖票,  没有票, 就不卖了.
        while(true) {
            //************** 一次完整的卖票动作从这里开始.
            lock.lock();
                // 没有票, 就不卖了.
                if (tickets <= 0) {         //线程1,线程2 线程3, 线程4
                    break;
                }

                //细节2: 加入休眠线程, 让程序出错的概率大一些.
                try {
                    Thread.sleep(50);   //单位是毫秒,  该方法的特点是: 在哪里睡, 到点后就在哪里醒来.     线程1,线程2 线程3, 线程4
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //走到这里, 说明有票, 卖票即可
                System.out.println(getName() + "  售卖出第 "+ tickets-- +" 张票");    //细节3: 这里要加入线程名, 即: 那个窗口卖的票.
           lock.unlock();
            //************** 一次完整的卖票动作到这里结束.
        }
    }
}
